/**
 * 
 */
package com.tcl.wip.client.Benchmark;

import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import org.h2.command.dml.ExecuteProcedure;

import com.tcl.wip.commons.hash.KetamaHashAlgorithm;

/**
 * @author zhaowen.zhuang
 * @Date Mar 19, 2015
 */
public class ConsistentHashing {

    public static void main(String[] args) throws InterruptedException {
        final KetamaHashAlgorithm ketama = KetamaHashAlgorithm.KETAMA_HASH;
        final TreeMap<Long, String> map = new TreeMap<>();
        for (int i = 0; i < 100; i++) {
            String uuid = UUID.randomUUID().toString();

            map.put(ketama.hash(ketama.md5(uuid), 0), uuid);
        }

        
        ExecutorService executor = Executors.newFixedThreadPool(10);
        long start = System.currentTimeMillis();
        int total = 10000000;
        for (int i = 0; i < total; i++) {
            executor.execute(new Runnable() {

                @Override
                public void run() {
                    String uuid = UUID.randomUUID().toString();
                    consistentHash(map, ketama.hash(ketama.md5(uuid), 0));

                }
            });
            
            if(i % 10000 == 0 ){
                System.out.println("subimt tasks count " + i );
            }
        }
        executor.shutdown();
        while(!executor.awaitTermination(10, TimeUnit.SECONDS)){
            System.out.println("wait for shutdown");
        }
        double tps = total/((System.currentTimeMillis() - start) / 1000 );
        System.out.println("tps : "  + tps);

    }


    // 一致性 hash
    private static String consistentHash(SortedMap<Long, String> map, long hashcode) {
        SortedMap<Long, String> tailMap = map.tailMap(hashcode);
        if (tailMap.isEmpty()) {
            hashcode = map.firstKey();
        } else {
            hashcode = tailMap.firstKey();
        }

        return map.get(hashcode);
    }
}
